package io.terminus.spzx.cart.service.impl;

import com.alibaba.fastjson.JSON;
import io.terminus.spzx.cart.service.CartService;
import io.terminus.spzx.consts.CartConstant;
import io.terminus.spzx.feign.product.ProductFeignClient;
import io.terminus.spzx.model.entity.h5.CartInfo;
import io.terminus.spzx.model.entity.product.ProductSku;
import io.terminus.spzx.utils.AuthContextUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author lichunlong lcl253137@alibaba-inc.com
 * @desc 购物车Service实现类
 * @date 2024-11-19
 */
@Service
@RequiredArgsConstructor
public class CartServiceImpl implements CartService {

    private final RedisTemplate<String, String> redisTemplate;

    private final ProductFeignClient productFeignClient;

    @Override
    public void addToCart(Long skuId, Integer skuNum) {
        // 获取当前登录用户的id
        Long userId = AuthContextUtil.getUserId();
        String cartKey = CartConstant.REDIS_USER_CART_KEY_PREFIX + userId;

        // 获取缓存对象
        Object cacheCartInfo = redisTemplate.opsForHash().get(cartKey, String.valueOf(skuId));
        CartInfo cartInfo;
        if (Objects.isNull(cacheCartInfo)) {
            // 当购物车中没用该商品的时候，则直接添加到购物车
            cartInfo = new CartInfo();
            cartInfo.setSkuId(skuId);
            cartInfo.setUserId(userId);
            cartInfo.setSkuNum(skuNum);
            cartInfo.setCreateTime(new Date());

            // 购物车数据是从商品详情得到
            ProductSku productSku = productFeignClient.getBySkuId(skuId);
            cartInfo.setSkuName(productSku.getSkuName());
            cartInfo.setCartPrice(productSku.getSalePrice());
            cartInfo.setImgUrl(productSku.getThumbImg());
        } else {
            cartInfo = JSON.parseObject(cacheCartInfo.toString(), CartInfo.class);
            cartInfo.setSkuNum(cartInfo.getSkuNum() + skuNum);
        }
        cartInfo.setIsChecked(1);
        cartInfo.setUpdateTime(new Date());

        // 将商品数据存储到购物车中
        redisTemplate.opsForHash().put(cartKey, String.valueOf(skuId), JSON.toJSONString(cartInfo));
    }

    @Override
    public List<CartInfo> getCartList() {
        String cartKey = getCartKey();

        // 获取缓存对象
        List<Object> cacheCartInfoList = redisTemplate.opsForHash().values(cartKey);

        return CollectionUtils.isEmpty(cacheCartInfoList) ? new ArrayList<>() : cacheCartInfoList.stream().map(cartInfoJSON -> JSON.parseObject(cartInfoJSON.toString(), CartInfo.class))
                .sorted((o1, o2) -> o2.getCreateTime().compareTo(o1.getCreateTime()))
                .collect(Collectors.toList());
    }

    @Override
    public void deleteCart(Long skuId) {
        String cartKey = getCartKey();

        //获取缓存对象
        redisTemplate.opsForHash().delete(cartKey, String.valueOf(skuId));
    }

    @Override
    public void checkCart(Long skuId, Integer isChecked) {
        String cartKey = getCartKey();

        Boolean hasKey = redisTemplate.opsForHash().hasKey(cartKey, String.valueOf(skuId));
        if (hasKey) {
            String cacheCartInfo = Objects.requireNonNull(redisTemplate.opsForHash().get(cartKey, String.valueOf(skuId))).toString();
            CartInfo cartInfo = JSON.parseObject(cacheCartInfo, CartInfo.class);
            cartInfo.setIsChecked(isChecked);
            redisTemplate.opsForHash().put(cartKey, String.valueOf(skuId), JSON.toJSONString(cartInfo));
        }
    }

    @Override
    public void allCheckCart(Integer isChecked) {
        String cartKey = getCartKey();

        // 获取缓存对象
        List<Object> cacheCartInfoList = redisTemplate.opsForHash().values(cartKey);
        if (!CollectionUtils.isEmpty(cacheCartInfoList)) {
            cacheCartInfoList.forEach(cacheCartInfo -> {
                CartInfo cartInfo = JSON.parseObject(cacheCartInfo.toString(), CartInfo.class);
                cartInfo.setIsChecked(isChecked);

                redisTemplate.opsForHash().put(cartKey, String.valueOf(cartInfo.getSkuId()), JSON.toJSONString(cartInfo));
            });
        }
    }

    @Override
    public void clearCart() {
        String cartKey = getCartKey();

        redisTemplate.delete(cartKey);
    }

    @Override
    public List<CartInfo> getAllChecked() {
        String cartKey = getCartKey();
        // 获取所有的购物车数据
        List<Object> cacheCartInfoList = redisTemplate.opsForHash().values(cartKey);

        // 过滤选中的购物车商品
        return CollectionUtils.isEmpty(cacheCartInfoList) ? new ArrayList<>() : cacheCartInfoList.stream().map(cartInfoJSON -> JSON.parseObject(cartInfoJSON.toString(), CartInfo.class))
                .filter(cartInfo -> cartInfo.getIsChecked() == 1)
                .collect(Collectors.toList());
    }

    @Override
    public void deleteChecked() {
        String cartKey = getCartKey();
        // 删除选中的购物项数据
        List<Object> objectList = redisTemplate.opsForHash().values(cartKey);
        if (!CollectionUtils.isEmpty(objectList)) {
            objectList.stream().map(cartInfoJSON -> JSON.parseObject(cartInfoJSON.toString(), CartInfo.class))
                    .filter(cartInfo -> cartInfo.getIsChecked() == 1)
                    .forEach(cartInfo -> redisTemplate.opsForHash().delete(cartKey, String.valueOf(cartInfo.getSkuId())));
        }
    }

    /**
     * 获取购物车key
     *
     * @return 购物车key
     */
    private String getCartKey() {
        // 获取当前登录用户的id
        Long userId = AuthContextUtil.getUserId();
        return CartConstant.REDIS_USER_CART_KEY_PREFIX + userId;
    }

}
